package com.qiyuesuo.file.service.impl;

import com.qiyuesuo.file.dao.FileMapper;
import com.qiyuesuo.file.pojo.FileData;
import com.qiyuesuo.file.service.FileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Service
public class FileServiceImpl implements FileService {

    @Autowired
    private FileMapper fileMapper;

    //文件输入流
    FileOutputStream fos;
    //文件输出流
    FileInputStream fis;
    //本地输出流
    OutputStream os;

    //文件上传
    @Override
    public Map<String, String> uploadFile(MultipartFile file) {
        Map<String, String> map = new HashMap<>();
        //获取文件上传时的名称（oldName）
        String oldName = file.getOriginalFilename();
        //获取后缀名
        String suffix = oldName.substring(oldName.lastIndexOf("."));
        //创建uuid
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        map.put("uuid", uuid);
        //文件新名
        String newName = uuid + suffix;

        //设置目录存储格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String format = sdf.format(new Date());
        //文件上传后存放的目录
        String uploadSavePath = "src/main/resources/file";
        //设置文件保存目录
        String catalog = uploadSavePath + "/" + format + "/";
        //设置文件保存路径
        String filePath = catalog + newName;

        //字节流输出文件
        try {
            byte[] bytes = file.getBytes();
            File target = new File(catalog);
            if (!target.exists()) {
                target.mkdirs();
            }
            //文件输出
            fos = new FileOutputStream(filePath);
            fos.write(bytes);

            map.put("msg", "文件上传成功");
        } catch (IOException e) {
            throw new RuntimeException("上传失败", e);
        } finally {
            //关流
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        //存储数据到数据库 id自增
        FileData fileData = new FileData();
        fileData.setSize(file.getSize());
        fileData.setType(file.getContentType());
        fileData.setOldName(oldName);
        fileData.setNewName(uuid);
        fileData.setFilePath(filePath);

        fileMapper.insertFileData(fileData);

        return map;
    }

    //文件下载
    @Override
    public void downloadFile(String newName, HttpServletResponse rs) {
        //设置响应类型
        rs.setContentType("multipart/form-data:");

        //根据uuid获取数据库里信息
        FileData fileData = fileMapper.selectByNewNme(newName);

        String oldName = fileData.getOldName();
        String suffix = oldName.substring(oldName.lastIndexOf("."));

        //设置相应头
        rs.addHeader("Content-Disposition", "attachment;fileName=" + newName + suffix);
        if (fileData == null) {
            rs.setStatus(410);
            return;
        }

        //获取文件
        File file = new File(fileData.getFilePath());

        //判断文件存在与否,不存在返回410状态码
        if (file.exists()) {
            try {
                fis = new FileInputStream(file);
                os = rs.getOutputStream();

                byte[] buffer = new byte[1024 * 8];
                int len = 0;
                while ((len = fis.read(buffer)) != -1) {
                    os.write(buffer, 0, len);
                }
            } catch (IOException e) {
                throw new RuntimeException("文件下载失败", e);
            } finally {
                try {
                    fis.close();
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } else {
            rs.setStatus(410);
        }
    }

    @Override
    public Map<String,FileData> getFileData(String newName) {
        Map<String,FileData>  map = new HashMap();

        //获取文件信息
        FileData fileData = fileMapper.selectByNewNme(newName);
        map.put("fileData", fileData);

        return map;
    }

}
